#!/bin/bash

set -e

REMOTE_HOST="218.244.141.86"
REMOTE_USER="root"
REMOTE_PASSWORD="Jason040515" 
BACKEND_DIR="/var/www/recipe-app/backend"
SSH_KEY="" 

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

log() {
    echo -e "${GREEN}[LOCAL $(date +'%H:%M:%S')] $1${NC}"
}

warn() {
    echo -e "${YELLOW}[LOCAL $(date +'%H:%M:%S')] 警告: $1${NC}"
}

error() {
    echo -e "${RED}[LOCAL $(date +'%H:%M:%S')] 错误: $1${NC}"
}

show_menu() {
    echo -e "${BLUE}================================${NC}"
    echo -e "${BLUE}       远程部署菜单${NC}"
    echo -e "${BLUE}================================${NC}"
    echo "1. 仅启动Spring项目"
    echo "2. 拉取代码并重新编译启动"
    echo "3. 重置数据库（执行step1-4）"
    echo "4. 重置数据库数据（清除数据+step4）"
    echo "5. 查看应用日志"
    echo -e "${BLUE}================================${NC}"
}

# 执行远程命令
execute_remote() {
    local command="$1"
    if command -v sshpass &> /dev/null; then
        sshpass -p "$REMOTE_PASSWORD" ssh -o StrictHostKeyChecking=no $REMOTE_USER@$REMOTE_HOST "$command"
    else
        ssh -o StrictHostKeyChecking=no $REMOTE_USER@$REMOTE_HOST "$command"
    fi
}

# 执行远程部署脚本
execute_remote_script() {
    local script_content="$1"
    if command -v sshpass &> /dev/null; then
        sshpass -p "$REMOTE_PASSWORD" ssh -o StrictHostKeyChecking=no $REMOTE_USER@$REMOTE_HOST "$script_content"
    else
        ssh -o StrictHostKeyChecking=no $REMOTE_USER@$REMOTE_HOST "$script_content"
    fi
}

# 选项1: 仅启动Spring项目
start_spring_only() {
    log "执行选项1: 仅启动Spring项目"
    
    execute_remote_script << 'EOF'
set -e

# 远程服务器的颜色定义和函数
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

log() {
    echo -e "${GREEN}[REMOTE $(date +'%H:%M:%S')] $1${NC}"
}

warn() {
    echo -e "${YELLOW}[REMOTE $(date +'%H:%M:%S')] 警告: $1${NC}"
}

error() {
    echo -e "${RED}[REMOTE $(date +'%H:%M:%S')] 错误: $1${NC}"
}

BACKEND_DIR="/var/www/recipe-app/backend"

log "步骤1: 进入项目目录"
cd "$BACKEND_DIR" || { error "目录不存在: $BACKEND_DIR"; exit 1; }

log "步骤2: 停止现有应用"
pkill -f "RecipeDB-0.0.1-SNAPSHOT.jar" || warn "没有找到运行中的应用"

log "步骤3: 启动新应用"
nohup java -jar target/RecipeDB-0.0.1-SNAPSHOT.jar > app.log 2>&1 &

log "步骤4: 等待应用启动(60s)..."
sleep 60

log "步骤5: 检查应用状态"
if lsof -i :8080 > /dev/null 2>&1; then
    log "应用启动成功，端口8080正在监听"
else
    error "应用启动失败，请检查日志: $BACKEND_DIR/app.log"
    exit 1
fi

log "Spring项目启动完成!"
EOF
}

# 选项2: 拉取并重新编译启动（使用强制拉取方法）
pull_and_rebuild() {
    log "执行选项2: 拉取代码并重新编译启动（强制拉取）"

    execute_remote_script << 'EOF'
set -e

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

log() {
    echo -e "${GREEN}[REMOTE $(date +'%H:%M:%S')] $1${NC}"
}

warn() {
    echo -e "${YELLOW}[REMOTE $(date +'%H:%M:%S')] 警告: $1${NC}"
}

error() {
    echo -e "${RED}[REMOTE $(date +'%H:%M:%S')] 错误: $1${NC}"
}

BACKEND_DIR="/var/www/recipe-app/backend"
CONFIG_FILE="$BACKEND_DIR/src/main/resources/application.properties"
CONFIG_BACKUP="/tmp/application.properties.backup.$$"

log "步骤1: 进入项目目录"
cd "$BACKEND_DIR" || { error "目录不存在: $BACKEND_DIR"; exit 1; }

log "步骤2: 备份当前配置文件"
if [ -f "$CONFIG_FILE" ]; then
    cp "$CONFIG_FILE" "$CONFIG_BACKUP"
    log "配置文件已备份到: $CONFIG_BACKUP"
else
    warn "配置文件不存在: $CONFIG_FILE"
fi

log "步骤3: 检查Git状态"
git status --porcelain

log "步骤4: 强制拉取最新代码（覆盖本地更改）"
git fetch --all
git reset --hard origin/main
git clean -fd

log "步骤5: 恢复服务器特定的配置文件"
if [ -f "$CONFIG_BACKUP" ]; then
    cp "$CONFIG_BACKUP" "$CONFIG_FILE"
    log "服务器配置文件已恢复"
    rm "$CONFIG_BACKUP"
else
    warn "没有找到配置文件备份，使用拉取的版本"
fi

log "步骤6: 验证代码状态"
git log --oneline -5

log "步骤7: Maven构建"
mvn clean package -DskipTests || { error "Maven构建失败"; exit 1; }

log "步骤8: 停止现有应用"
pkill -f "RecipeDB-0.0.1-SNAPSHOT.jar" || warn "没有找到运行中的应用"

log "步骤9: 等待进程完全停止"
sleep 5

log "步骤10: 启动新应用"
nohup java -jar target/RecipeDB-0.0.1-SNAPSHOT.jar > app.log 2>&1 &

log "步骤11: 等待应用启动(60s)..."
sleep 60

log "步骤12: 检查应用状态"
if lsof -i :8080 > /dev/null 2>&1; then
    log "应用启动成功，端口8080正在监听"
else
    error "应用启动失败，请检查日志: $BACKEND_DIR/app.log"
    log "=== 应用日志最后50行 ==="
    tail -n 50 "$BACKEND_DIR/app.log"
    exit 1
fi

log "代码拉取和重新编译启动完成!"
EOF
}

# 选项3: 重置数据库
reset_database() {
    log "执行选项3: 重置数据库（执行step1-4）"

    execute_remote_script << 'EOF'
set -e

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

log() {
    echo -e "${GREEN}[REMOTE $(date +'%H:%M:%S')] $1${NC}"
}

warn() {
    echo -e "${YELLOW}[REMOTE $(date +'%H:%M:%S')] 警告: $1${NC}"
}

error() {
    echo -e "${RED}[REMOTE $(date +'%H:%M:%S')] 错误: $1${NC}"
}

BACKEND_DIR="/var/www/recipe-app/backend"
SQL_DIR="/var/www/recipe-app/backend/sql"
CONFIG_FILE="$BACKEND_DIR/src/main/resources/application.properties"
CONFIG_BACKUP="/tmp/application.properties.backup.$$"

log "步骤1: 进入项目目录"
cd "$BACKEND_DIR" || { error "目录不存在: $BACKEND_DIR"; exit 1; }

log "步骤2: 备份当前配置文件"
if [ -f "$CONFIG_FILE" ]; then
    cp "$CONFIG_FILE" "$CONFIG_BACKUP"
    log "配置文件已备份到: $CONFIG_BACKUP"
else
    warn "配置文件不存在: $CONFIG_FILE"
fi

log "步骤3: 强制拉取最新代码（确保SQL文件最新）"
git fetch --all
git reset --hard origin/main
git clean -fd

log "步骤4: 恢复服务器特定的配置文件"
if [ -f "$CONFIG_BACKUP" ]; then
    cp "$CONFIG_BACKUP" "$CONFIG_FILE"
    log "服务器配置文件已恢复"
    rm "$CONFIG_BACKUP"
else
    warn "没有找到配置文件备份，使用拉取的版本"
fi

log "步骤5: 验证SQL文件存在"
ls -la "$SQL_DIR/" || error "SQL目录不存在"

log "步骤6: 执行数据库更新"
sudo -u postgres psql -d recipedb -f "$SQL_DIR/step1清空数据库.sql"
sudo -u postgres psql -d recipedb -f "$SQL_DIR/step2数据结构.sql"
sudo -u postgres psql -d recipedb -f "$SQL_DIR/step3触发器与函数.sql"
sudo -u postgres psql -d recipedb -f "$SQL_DIR/step4测试数据.sql"
sudo -u postgres psql -d recipedb -f "$SQL_DIR/step5测试用户.sql"

log "步骤7: 验证数据库表创建"
sudo -u postgres psql -d recipedb -c "
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'public'
ORDER BY table_name;
"

log "数据库重置完成!"
EOF
}

# 选项4: 重置数据库数据
reset_database_data() {
    log "执行选项4: 重置数据库数据"

    execute_remote_script << 'EOF'
set -e

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

log() {
    echo -e "${GREEN}[REMOTE $(date +'%H:%M:%S')] $1${NC}"
}

warn() {
    echo -e "${YELLOW}[REMOTE $(date +'%H:%M:%S')] 警告: $1${NC}"
}

error() {
    echo -e "${RED}[REMOTE $(date +'%H:%M:%S')] 错误: $1${NC}"
}

BACKEND_DIR="/var/www/recipe-app/backend"
SQL_DIR="/var/www/recipe-app/backend/sql"
CONFIG_FILE="$BACKEND_DIR/src/main/resources/application.properties"
CONFIG_BACKUP="/tmp/application.properties.backup.$$"

log "步骤1: 进入项目目录"
cd "$BACKEND_DIR" || { error "目录不存在: $BACKEND_DIR"; exit 1; }

log "步骤2: 备份当前配置文件"
if [ -f "$CONFIG_FILE" ]; then
    cp "$CONFIG_FILE" "$CONFIG_BACKUP"
    log "配置文件已备份到: $CONFIG_BACKUP"
else
    warn "配置文件不存在: $CONFIG_FILE"
fi

log "步骤3: 强制拉取最新代码（确保SQL文件最新）"
git fetch --all
git reset --hard origin/main
git clean -fd

log "步骤4: 恢复服务器特定的配置文件"
if [ -f "$CONFIG_BACKUP" ]; then
    cp "$CONFIG_BACKUP" "$CONFIG_FILE"
    log "服务器配置文件已恢复"
    rm "$CONFIG_BACKUP"
else
    warn "没有找到配置文件备份，使用拉取的版本"
fi

log "步骤5: 执行数据清除和重置"
# 检查清除数据.sql文件是否存在
if [ -f "$SQL_DIR/清除数据.sql" ]; then
    sudo -u postgres psql -d recipedb -f "$SQL_DIR/清除数据.sql"
else
    error "清除数据.sql文件不存在: $SQL_DIR/清除数据.sql"
    exit 1
fi

sudo -u postgres psql -d recipedb -f "$SQL_DIR/step4测试数据.sql"
sudo -u postgres psql -d recipedb -f "$SQL_DIR/step5测试用户.sql"

log "数据库数据重置完成!"
EOF
}

# 选项5: 查看应用日志
view_app_logs() {
    log "执行选项5: 查看应用日志"
    
    execute_remote_script << 'EOF'
set -e

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

log() {
    echo -e "${GREEN}[REMOTE $(date +'%H:%M:%S')] $1${NC}"
}

warn() {
    echo -e "${YELLOW}[REMOTE $(date +'%H:%M:%S')] 警告: $1${NC}"
}

BACKEND_DIR="/var/www/recipe-app/backend"

echo -e "${YELLOW}=== 应用状态检查 ===${NC}"

echo -e "${GREEN}1. Java进程状态:${NC}"
ps aux | grep java | grep -v grep || echo "没有找到Java进程"

echo -e "${GREEN}2. 端口监听状态:${NC}"
netstat -tlnp | grep 8080 || echo "端口8080未监听"

echo -e "${GREEN}3. 应用日志最后100行:${NC}"
if [ -f "$BACKEND_DIR/app.log" ]; then
    tail -n 100 "$BACKEND_DIR/app.log"
else
    echo "日志文件不存在: $BACKEND_DIR/app.log"
fi

echo -e "${GREEN}4. JAR文件状态:${NC}"
ls -la "$BACKEND_DIR/target/RecipeDB-0.0.1-SNAPSHOT.jar" 2>/dev/null || echo "JAR文件不存在"

EOF
}

main() {
    log "开始远程部署到 $REMOTE_HOST..."
    
    show_menu
    
    read -p "请选择部署选项 (1-5): " choice
    
    case $choice in
        1)
            start_spring_only
            ;;
        2)
            pull_and_rebuild
            ;;
        3)
            reset_database
            ;;
        4)
            reset_database_data
            ;;
        5)
            view_app_logs
            ;;
        *)
            error "无效的选择: $choice"
            exit 1
            ;;
    esac
    
    log "远程部署执行完毕"
}

main "$@"